package com.apinji.alipay.service.serviceimpl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.apinji.alipay.common.AlipayErrorCodeEnum;
import com.apinji.alipay.dto.AlipayRefundDto;
import com.apinji.alipay.dto.AlipayRefundQueryDto;
import com.apinji.alipay.protocol.AlipayTradeFastpayRefundQeryResponse;
import com.apinji.alipay.protocol.AlipayTradeRefundResponse;
import com.apinji.alipay.sdk.AlipaySdkConfig;
import com.apinji.alipay.service.AlipayRefundService;
import com.apinji.common.data.ConsumeTypeEnum;
import com.apinji.common.data.PayChannelEnum;
import com.apinji.common.data.PayStatusEnum;
import com.apinji.common.domain.TransactionRecord;
import com.apinji.common.domain.mapper.TransactionRecordMapper;
import com.apinji.common.domain.wrapper.Reply;
import com.apinji.common.plugin.Mutual;
import com.apinji.common.plugin.StrUtils;
import com.apinji.common.plugin.fastjson.JSONUtils;
import com.apinji.unionpay.sdk.SDKConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;

@Service
public class AlipayRefundServiceImpl implements AlipayRefundService {

    @Autowired
    private TransactionRecordMapper transactionRecordMapper;

    @Override
    public Reply refund(AlipayRefundDto alipayRefundDto) throws Exception {
        String userUUID =  alipayRefundDto.getUserUUID();
        String consumeOutOrderId = alipayRefundDto.getConsumeOutOrderId();

        //1.先获取到交易流水，主要是  queryId
        List<TransactionRecord> records = transactionRecordMapper.listRecords(consumeOutOrderId, userUUID, PayStatusEnum.SUCCESS_DEAL.getStatus(), ConsumeTypeEnum.PAYMENT_TYPE.getCode());
        if(null == records || records.size() == 0) {
            return Mutual.notExist("没有查到需要退款的交易记录");
        }
        if(records.size() > 1) {
            return Mutual.haveExist("存在多条需要退款的交易记录");
        }
        TransactionRecord transactionRecord = records.get(0);
        //
        if(transactionRecord.getConsumeType() != ConsumeTypeEnum.PAYMENT_TYPE.getCode()) {
            return Mutual.serverError("该笔订单不是支付订单，不能进行退款操作");
        }
        if(transactionRecord.getPayChannel() != PayChannelEnum.ALIPAY_CHANNEL.getCode()) {
            return Mutual.serverError("该笔订单不是支付宝支付订单，不是进行支付宝退款操作");
        }
        if(StrUtils.isEmpty(transactionRecord.getQueryId())) {
            return Mutual.serverError("没有查询到订单记录");
        }
        //退款金额校验
        if(transactionRecord.getTxnAmt() < alipayRefundDto.getTxnAmt()) {
            return Mutual.invalidParam("退款金额超出已支付金额");
        }

        //
        AlipaySdkConfig alipaySdkConfig = AlipaySdkConfig.getInstance();
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(alipaySdkConfig.getGatewayUrl(),
                alipaySdkConfig.getAppId(),
                alipaySdkConfig.getMerchantPrivateKey(),
                "json", alipaySdkConfig.getCharset(),
                alipaySdkConfig.getAlipayPublicKey(),
                alipaySdkConfig.getSignType());


        //设置请求参数
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();

        //商户订单号，商户网站订单系统中唯一订单号
        String out_trade_no = alipayRefundDto.getConsumeOutOrderId();
        //支付宝交易号
        String trade_no = transactionRecord.getQueryId();
        //请二选一设置
        //需要退款的金额，该金额不能大于订单金额，必填
        String refund_amount = ((double)alipayRefundDto.getTxnAmt()/100) + "";
        //退款的原因说明
        String refund_reason = alipayRefundDto.getRefundDesc();
        //标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传
        String out_request_no = alipayRefundDto.getRefundOutOderId();

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"trade_no\":\""+ trade_no +"\","
                + "\"refund_amount\":\""+ refund_amount +"\","
                + "\"refund_reason\":\""+ refund_reason +"\","
                + "\"out_request_no\":\""+ out_request_no +"\"}");

        //请求
        String result = alipayClient.execute(alipayRequest).getBody();
        JSONObject jsonObject = JSONUtils.parseJsonObject(result);
        //
        AlipayTradeRefundResponse response = JSONUtils.toJavaObject(jsonObject.getJSONObject("alipay_trade_refund_response"), AlipayTradeRefundResponse.class);

        //======================
        TransactionRecord refundRecord = new TransactionRecord();

        refundRecord.setId(StrUtils.uuid());
        refundRecord.setUserUUID(alipayRefundDto.getUserUUID());
        refundRecord.setCreateTime(new Date());
        refundRecord.setCardNo(transactionRecord.getCardNo());
        refundRecord.setOrderId(transactionRecord.getOrderId());
        //
        //refundRecord.setFrontUrl(alipayRefundDto.getFrontUrl());
        refundRecord.setConsumeType(ConsumeTypeEnum.REFUND_TYPE.getCode());//退款
        refundRecord.setConsumeTypeName(ConsumeTypeEnum.REFUND_TYPE.getName());

        refundRecord.setOutOrderId(alipayRefundDto.getRefundOutOderId());//对外的订单编号 UUID
        refundRecord.setPayChannel(PayChannelEnum.UNIONPAY_CHANNEL.getCode());

        refundRecord.setCardNo(response.getBuyerUserId());
        refundRecord.setOrderDesc(refund_reason);

        //refundRecord.setTxnType(txnType);
        //refundRecord.setTxnSubType(txbSubType);
        //refundRecord.setBizType(bizType);
        //refundRecord.setChannelType(channelType);//渠道类型
        //refundRecord.setMerId(SDKConfig.getConfig().getMerId());
        refundRecord.setTxnTime(response.getGmtRefundPay());//退款支付时间
        refundRecord.setTxnAmt((int)(response.getRefundFee()*100));//订单金额，单位 分，不含小数点
        //refundRecord.setCurrencyCode(currencyCode);//交易币种
        //refundRecord.setToken(transactionRecord.getToken());
        //
        refundRecord.setPayStatus(PayStatusEnum.ORDER_CREATE.getStatus());
        refundRecord.setMemo(PayStatusEnum.ORDER_CREATE.getName());//1
        //
        refundRecord.setQueryId(response.getTradeNo());

        //
        transactionRecordMapper.addTransactionRecord(refundRecord);
        //======================

        //退款成功  且资金发生了变化
        if(null != response && response.getCode() == AlipayErrorCodeEnum.SUCCESS.getCode() && response.getFundChange().equals("Y")) {
            transactionRecordMapper.updatePayStatus(alipayRefundDto.getRefundOutOderId(), PayStatusEnum.SUCCESS_DEAL.getStatus(), PayStatusEnum.SUCCESS_DEAL.getName());
            return Mutual.success(refundRecord);
        }
        //
        return Mutual.alipayResponseError(response);
    }


    @Override
    public Reply refundQuery(AlipayRefundQueryDto alipayRefundQueryDto) throws Exception {
        TransactionRecord transactionRecord = transactionRecordMapper.getOneItemByUser(alipayRefundQueryDto.getId(), alipayRefundQueryDto.getUserUUID());
        if(null == transactionRecord || StrUtils.isEmpty(transactionRecord.getId())) {
            return Mutual.notExist("交易记录不存在");
        }
        //
        AlipaySdkConfig alipaySdkConfig = AlipaySdkConfig.getInstance();
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(alipaySdkConfig.getGatewayUrl(),
                alipaySdkConfig.getAppId(),
                alipaySdkConfig.getMerchantPrivateKey(),
                "json", alipaySdkConfig.getCharset(),
                alipaySdkConfig.getAlipayPublicKey(),
                alipaySdkConfig.getSignType());

        //设置请求参数
        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();

        //商户订单号，商户网站订单系统中唯一订单号
        String out_trade_no = transactionRecord.getOutOrderId();
        //支付宝交易号
        String trade_no = transactionRecord.getQueryId();
        //请二选一设置
        //请求退款接口时，传入的退款请求号，如果在退款请求时未传入，则该值为创建交易时的外部交易号，必填
        String out_request_no = transactionRecord.getOutOrderId();

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                +"\"trade_no\":\""+ trade_no +"\","
                +"\"out_request_no\":\""+ out_request_no +"\"}");

        //请求
        String result = alipayClient.execute(alipayRequest).getBody();
        JSONObject jsonObject = JSONUtils.parseJsonObject(result);
        AlipayTradeFastpayRefundQeryResponse response = JSONUtils.toJavaObject(jsonObject.getJSONObject("alipay_trade_fastpay_refund_query_response"), AlipayTradeFastpayRefundQeryResponse.class);

        if(null != response && response.getCode() == AlipayErrorCodeEnum.SUCCESS.getCode()) {
            return Mutual.success(response);
        }
        return Mutual.alipayResponseError(response);
    }

}
